package com.skiving.cloud.admin.controller;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.skiving.cloud.admin.entity.SysMenu;
import com.skiving.cloud.admin.entity.SysTenantMenu;
import com.skiving.cloud.admin.service.SysMenuService;
import com.skiving.cloud.admin.service.SysTenantMenuService;
import com.skiving.cloud.auth.util.UserUtil;
import com.skiving.cloud.common.utils.PageParameter;
import com.skiving.cloud.common.utils.ReturnT;
import com.skiving.cloud.common.utils.UuidUtil;
import com.skiving.cloud.constant.AdminConstant;
import com.skiving.cloud.logutils.OperateLogLocal;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.*;
import org.noear.solon.core.util.MimeType;
import com.skiving.cloud.admin.entity.SysTenant;
import com.skiving.cloud.admin.service.SysTenantService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 租户表 控制层。
 *
 * @author skivingcloud
 * @since 2025-03-08
 */
@Slf4j
@Controller
@Api("租户表接口")
@Mapping("/sysTenant")
@Produces(MimeType.APPLICATION_JSON_UTF8_VALUE)
public class SysTenantController {

    @Inject
    private SysTenantService sysTenantService;
    @Inject
    private SysTenantMenuService sysTenantMenuService;
    @Inject
    private SysMenuService sysMenuService;

    /**
     * 添加租户表。
     *
     * @param sysTenant 租户表
     * @return {@code true} 添加成功，{@code false} 添加失败
     */
    @Post
    @Mapping("/save")
    @ApiOperation("保存租户表")
    @OperateLogLocal(module="系统管理-租户管理", description = "新增租户管理")
    public ReturnT<Boolean> save(@Body @ApiParam("租户表") SysTenant sysTenant) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.where(SysTenant::getTenantCode).eq(sysTenant.getTenantCode());
        boolean exists = sysTenantService.exists(queryWrapper);
        if(exists){
            return ReturnT.error("租户编号重复！");
        }
        sysTenant.setId(UuidUtil.get32UUID());
        sysTenant.setCreater(UserUtil.getCurrentUser().getId());
        sysTenant.setCreateTime(LocalDateTime.now());
        return ReturnT.ok(sysTenantService.save(sysTenant));
    }

    /**
     * 根据主键删除租户表。
     *
     * @param id 主键
     * @return {@code true} 删除成功，{@code false} 删除失败
     */
    @Get
    @Mapping("/remove/{id}")
    @ApiOperation("根据主键租户表")
    @OperateLogLocal(module="系统管理-租户管理", description = "删除租户管理")
    public ReturnT<Boolean> remove(@Path @ApiParam("租户表主键") String id) {
        if(AdminConstant.SUPER_ADMIN_TENANT_ID.equals(id)) {
            return ReturnT.error("超级管理员租户为内置租户，请勿删除！");
        }
        return ReturnT.ok(sysTenantService.removeById(id));
    }

    /**
     * 根据主键更新租户表。
     *
     * @param sysTenant 租户表
     * @return {@code true} 更新成功，{@code false} 更新失败
     */
    @Post
    @Mapping("/update")
    @ApiOperation("根据主键更新租户表")
    @OperateLogLocal(module="系统管理-租户管理", description = "修改租户管理")
    public ReturnT<Boolean> update(@Body @ApiParam("租户表主键") SysTenant sysTenant) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.where(SysTenant::getTenantCode).eq(sysTenant.getTenantCode())
                .and(SysTenant::getId).ne(sysTenant.getId());
        boolean exists = sysTenantService.exists(queryWrapper);
        if(exists){
            return ReturnT.error("租户编号重复！");
        }
        sysTenant.setModUser(UserUtil.getCurrentUser().getId());
        sysTenant.setModTime(LocalDateTime.now());
        return ReturnT.ok(sysTenantService.updateById(sysTenant));
    }

    /**
     * 查询所有租户表。
     *
     * @return 所有数据
     */
    @Get
    @Mapping("/list")
    @ApiOperation("查询所有租户表")
    public ReturnT<List<SysTenant>> list() {
        return ReturnT.ok(sysTenantService.list());
    }

    /**
     * 根据租户表主键获取详细信息。
     *
     * @param id 租户表主键
     * @return 租户表详情
     */
    @Get
    @Mapping("/getInfo/{id}")
    @ApiOperation("根据主键获取租户表")
    public ReturnT<SysTenant> getInfo(@Path @ApiParam("租户表主键") String id) {
        return ReturnT.ok(sysTenantService.getById(id));
    }

    /**
     * 分页查询租户表。
     *
     * @param parameter 分页对象
     * @return 分页对象
     */
    @Post
    @Mapping("/page")
    @ApiOperation("分页查询租户表")
    public ReturnT<Page<SysTenant>> page(@Body @ApiParam("分页信息") PageParameter<SysTenant> parameter) {
        return ReturnT.ok(sysTenantService.queryByPage(parameter));
    }

    /**
     * 查询租户信息{key:'', value:''}
     *
     * @return 租户信息{key:'', value:''}
     */
    @ApiOperation("查询租户信息")
    @Get
    @Mapping("/getTenantSelect")
    public ReturnT<List<Map<String, Object>>> getTenantSelect() {
        List<Map<String, Object>> list = sysTenantService.getTenantSelect();
        return ReturnT.ok(list);
    }

    /**
     * 删除租户
     * @param ids 租户id
     * @return 删除结果
     */
    @ApiOperation("删除租户")
    @Post
    @Mapping("/delete")
    @OperateLogLocal(module="系统管理-租户管理", description = "删除租户")
    public ReturnT<String> delete(@Body List<String> ids){
        try{
            if(ids.contains(AdminConstant.SUPER_ADMIN_TENANT_ID)) {
                return ReturnT.error("超级管理员租户为内置租户，请勿删除！");
            }
            sysTenantService.deleteBatch(ids);
            return ReturnT.ok("删除租户成功");
        }catch(Exception e){
            log.error("删除租户失败", e);
            return ReturnT.error("删除租户失败");
        }
    }

    /**
     * 根据租户id加载资源树权限
     *
     * @param id 角色id
     * @return 资源权限
     */
    @Get
    @Mapping("getSysTenantResTree/{id}")
    @ApiOperation("根据租户id加载资源树")
    public ReturnT<Map<String, Object>> getSysTenantResTree(@Path("id") String id){
        List<SysMenu> list = sysMenuService.getMenuList();
        List<SysTenantMenu> tenantRes;
        tenantRes = sysTenantMenuService.getResTreeByTenantId(id);
        Map<String, Object> res = new HashMap<>();
        res.put("tree", list);
        res.put("tenantRes", tenantRes);
        return ReturnT.ok(res);
    }

    /**
     * 设置租户资源范围
     *
     * @param tenant 租户
     * @return 结果
     */
    @Post
    @Mapping("setSysTenantMenu")
    @ApiOperation("设置租户资源范围")
    @OperateLogLocal(module="系统管理-租户管理", description = "设置租户资源范围")
    public ReturnT<String> setSysTenantMenu(@Body SysTenant tenant) {
        try {
            sysTenantMenuService.setSysTenantMenu(tenant);
            return ReturnT.ok();
        } catch (Exception e) {
            log.error("设置资源权限失败", e);
            return ReturnT.error("设置资源权限失败");
        }
    }
}
